import { Injectable } from '@angular/core';
import { Subject, Subscription, filter } from 'rxjs';
import { BroadcastEvent, BroadcastListener, BroadcastMessage } from './broadcast.models';

/**
 * 广播服务
 * 
 * 功能：
 * - 提供组件间通信机制，实现发布-订阅模式
 * - 支持命名事件广播和监听
 * - 单例服务，全局可用
 * 
 * 架构：
 * ```
 * ComponentA → BroadcastService.broadcast() → ComponentB → BroadcastService.on()
 * ```
 * 
 * 使用场景：
 * - 跨模块事件通知
 * - 解耦组件间通信
 * - 全局事件分发
 * 
 * 示例：
 * ```typescript
 * // 发送事件
 * broadcastService.broadcast('user-login', { userId: '123', userName: 'John' });
 * 
 * // 监听事件
 * const subscription = broadcastService.on('user-login', (event, args) => {
 *   console.log('User logged in:', args);
 * });
 * 
 * // 取消订阅
 * subscription.unsubscribe();
 * ```
 */
@Injectable({
  providedIn: 'root'
})
export class BroadcastService {
  /** 广播消息主题 - 用于发布和订阅消息 */
  private readonly broadcastSubject = new Subject<BroadcastMessage>();

  /**
   * 广播事件
   * 
   * @param name - 事件名称
   * @param args - 事件参数（可变参数）
   */
  broadcast(name: string, ...args: Array<unknown>): void {
    const message: BroadcastMessage = {
      name,
      args: args.length > 0 ? args : undefined
    };
    this.broadcastSubject.next(message);
  }

  /**
   * 监听指定名称的事件
   * 
   * @param name - 要监听的事件名称
   * @param listener - 事件回调函数
   * @returns Subscription 订阅对象，用于取消订阅
   */
  on(name: string, listener: BroadcastListener): Subscription {
    return this.broadcastSubject.asObservable().pipe(
      filter((message) => message.name === name)
    ).subscribe((message) => {
      const event: BroadcastEvent = {
        name: message.name
      };
      // 展开参数数组传递给监听器
      if (message.args && message.args.length > 0) {
        listener(event, ...message.args);
      } else {
        listener(event);
      }
    });
  }
}